package base.xml.demo01;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;

import java.io.File;
import java.util.List;

/**
 * https://www.cnblogs.com/forlina/archive/2011/06/09/2076534.html
 */
public class TestCase {

    /**
     * Element 日常操作
     */
    @Test
    public void testCase1() throws Exception {
        SAXReader saxReader = new SAXReader();
//        Document document = DocumentHelper.parseText("<?xml version=\"1.0\" encoding=\"utf-8\"?><classroom grade=\"primary5\"><persons><teacher id=\"1\"><property name=\"name\" value=\"laosi\"/><property name=\"age\" value=\"24\"/></teacher><students><student id=\"1\"><property name=\"name\" value=\"lisi\"/><property name=\"age\" value=\"12\"/></student><student id=\"2\"><property name=\"name\" value=\"zhangsan\"/><property name=\"age\" value=\"12\"/></student><student id=\"3\"><property name=\"name\" value=\"wangwu\"/><property name=\"age\" value=\"12\"/></student></students></persons></classroom>");
//        Document document = saxReader.read(TestCase.class.getClassLoader().getResource("dom.xml").openStream());
        Document document = saxReader.read(new File("E:/ws/CoreJava/src/main/resources/dom.xml"));
        Element root = document.getRootElement();
        //获取root根元素下所有子元素
        for (Element element : root.elements()) {
            System.out.println(element.getName());
        }
        // 获取persons标签下students元素
        Element students = root.element("persons").element("students");
        System.out.println(students);

        // 获取persons标签下students标签下的student元素
        List<Element> studentList = root.element("persons").element("students").elements();
        for (Element element : studentList) {
            System.out.println(element.getName()  +": "+ element.attributeValue("id"));
        }

        // Element只能一级一级往下获取子Element，跳空获取不到子Element：比如从root根元素获取不到孙子students元素，只能先获取root的子元素persons，然后获取persons的子元素students
        System.out.println("------------------跳空获取不到子元素---------------------");
//        List<Element> stus = root.elements("//student");//类似Node的这种根据xPath方式也是获取不到Element的
        List<Element> stus = root.elements("student");
        for (Element element : stus) {
            System.out.println(element.getName());
        }
        System.out.println("孙子元素获取不到："+root.element("students"));
        System.out.println("------------------非跳空获取子元素---------------------");
        System.out.println(root.element("persons").elements("students").size());
    }

    /**
     * Node日常操作
     *
     * Node 和 Element区别:
     * Element：一个标签对既是一个Element
     * Node：把每个Element分割成零碎的一块块，往大了讲能代表 Element，往小了讲能代表 attribute
     */
    @Test
    public void testCase2_1() throws Exception {
        SAXReader saxReader = new SAXReader();
        Document root = saxReader.read(new File("E:/ws/CoreJava/src/main/resources/dom.xml"));
        Node classroom = root.selectSingleNode("classroom");
        System.out.println("获取唯一Node："+classroom.asXML());

        System.out.println("--------------------------直接遍历重孙节点：选择文档中所有的student节点-----------------------");
        for (Node node : root.selectNodes("//student")) {
            System.out.println(node.asXML());
            System.out.println("---------------------------------");
        }

        System.out.println("----------------获取第一个student节点--------------------");
        System.out.println(root.selectSingleNode("/classroom/persons/students/student").asXML());

        System.out.println("-----------------------获取persons下的所有节点------------------------");
        List<Node> persons = root.selectNodes("/classroom/persons/*");
        for (Node node : persons) {
            System.out.println(node.asXML());
        }

        System.out.println("---------------------选择有3个祖先的节点----------------------");
        List<Node> students = root.selectNodes("/*/*/*/student");
        for (Node node : students) {
            System.out.println(node.asXML());
        }
    }

    @Test
    public void testCase2_2() throws Exception {
        SAXReader saxReader = new SAXReader();
        Document root = saxReader.read(new File("E:/ws/CoreJava/src/main/resources/dom.xml"));

        System.out.println("-----------------//AAA[1]/BBB: 选择第一个AAA下的BBB元素: 选择第2个student下的第2个property节点--------------");
        Node node = root.selectSingleNode("//student[2]/property[2]");
        System.out.println(node.asXML());

        System.out.println("-----------------//AAA/BBB[1]: 选择所有AAA的第一个BBB元素: 选择所有student下的第2个property节点----------------------");
        List<Node> nodes = root.selectNodes("//student/property[2]");
        for (Node ps : nodes) {
            System.out.println(ps.asXML());
        }

        System.out.println("--------------//AAA/BBB[last()]：选择所有AAA的最后一个BBB元素：选择所有student下的最后一个property节点-----------------------");
        nodes = root.selectNodes("//student/property[last()]");
        for (Node ps : nodes) {
            System.out.println(ps.asXML());
        }
    }

    @Test
    public void testCase2_3() throws Exception {
        SAXReader saxReader = new SAXReader();
        Document root = saxReader.read(new File("E:/ws/CoreJava/src/main/resources/dom.xml"));

        System.out.println("---------------//@id：选择所有的id属性节点--------------");
//        List<Node> ids = root.selectNodes("//*[@id]");//所有包含id属性的节点
        List<Node> ids = root.selectNodes("//@id");//所有id节点
        for (Node id : ids) {
            System.out.println(id.asXML());
        }

        System.out.println("--------------//BBB[@id]：选择具有id属性的BBB元素---------");
        List<Node> teachers = root.selectNodes("//teacher[@id]");
        for (Node teacher : teachers) {
            System.out.println(teacher.asXML());
        }

        System.out.println("------------//BBB[@id='b1'] ：选择含有属性id并且其值为b1的BBB元素--------------");
//        List<Node> properties = root.selectNodes("//student/property");
        List<Node> properties = root.selectNodes("//student/property[@value='lisi']");
        for (Node property : properties) {
            System.out.println(property.asXML());
        }
    }

    /**
     * 如果我们的XPath表达式以 "/" 开头，那么表示相对于整个文档进行搜索；
     * 如果我们的XPath表达式以节点（标签）名开头，那么表示相对于调用搜索方法的节点进行搜索；
     */
    @Test
    public void testCase3() throws Exception {
        SAXReader saxReader = new SAXReader();
        Document root = saxReader.read(new File("E:/ws/CoreJava/src/main/resources/dom.xml"));

        // 首先我们拿到了student的父标签 students
        Node students = root.selectSingleNode("/classroom/persons/students");
        // 以下两种方式搜索的结果list1和list2是相同的
        List<?> list1 = students.selectNodes("/classroom/persons/students/student"); // 以 "/" 开头
        List<?> list2 = students.selectNodes("student"); // 以节点名开头
//        List<?> list3 = students.selectNodes("/student"); // 获取不到数据
        System.out.println(list1.size());// 3
        System.out.println(list2.size());// 3
    }

    @Test
    public void testCase5() throws Exception {
        SAXReader saxReader = new SAXReader();
        Document root = saxReader.read(new File("E:/ws/CoreJava/src/main/resources/dom.xml"));

        Node classroom = root.selectSingleNode("classroom");
        System.out.println(classroom.asXML());
    }
}
